import shipLocationService from '@/services/ShipLocationService'
import moment from 'moment'
import config from '@/config'
// 绘制船舶图标
import '@static/js/leaflet-trackSymbol.js'
import '@static/js/leaflet-trackLayer.js'
import './comp/FocusMarker'

const SHIP_QUERY_INTERVAL = 3000

class DrawShip {

  map = null
  // 船位数组
  shipSet = {};
  // 用于存储船舶符号的数组
  shipMarkers = {};
  // 船舶标签
  shipLabels = {};
  // 最后查询船位使用的ais时间
  lastAisTime = null;
  // 船位查询定时器
  queryShipTimer = 0;
  hideAisLayer = false;

  static getInstance () {
    if (!DrawShip.instance) {
      DrawShip.instance = new DrawShip()
    }
    return DrawShip.instance
  }

  init (mapobj) {
    this.colorMap = {};

    this.map = mapobj
    // 船舶绘制层
    this.shipLayer = L.trackLayer()
    this.map.on('zoomend', (e) => {
      this.lastAisTime = null
      this.stopQueryShipInBound()
      if (e.target.getZoom() > 10) {
        this.hideAisLayer || this.shipLayer.addTo(this.map)
        if (this.prevZoomLevel <= 10) {
          // 清除最后ais查询时间
          this.lastAisTime = 0
        }
        this.startQueryShipInBound()
      } else {
        // console.log('layer is:::::', this.shipLayer, this.map)
        // this.map.removeLayer(this.shipLayer)
        this.shipLayer.removeFrom(this.map)
        this.stopQueryShipInBound()
        // this.hideShips()
      }
      this.resetShipLabels(e.target.getZoom())
      this.prevZoomLevel = e.target.getZoom()
    });
    this.map.on('movestart', e => {
      this.lastAisTime = null
    })

    this.map.on('zoomstart', e => {
      this.stopQueryShipInBound()
    })

    config.SHIP_COLOR_ARRAY.forEach(row => {
      row.typeArray.forEach(type => {
        this.colorMap[type] = row.color
      })
    })

    window.addEventListener('message', e => {
      if (e.data && e.data.type === 'hideAisLayer') {
        this.hideAisLayer = e.data.value
        if (e.data.value) {
          if (this.shipLayer) {
            this.shipLayer.removeFrom(this.map)
            this.stopQueryShipInBound()
          }
        } else {
          if (this.map.getZoom() > 10) {
            this.shipLayer.addTo(this.map)
            this.startQueryShipInBound()
          }
        }
      }
    })
  }






  // let removeLayerById = id => {
  //   let idx = this.drawObject.findIndex(obj => obj._leaflet_id === id);
  //   let layer = this.drawObject[idx];
  //   this.drawObject.splice(idx, 1);
  //   layer.remove();
  // }
  //
  // let showLayerAtMapById = id => {
  //   let layer = this.drawObject.find(obj => obj._leaflet_id === id);
  //   if (layer.getBound) {
  //     this.map.fitBounds(layer.getBounds());
  //   } else if (layer._bounds) {
  //     this.map.fitBounds(layer._bounds);
  //   } else if (layer.getLatLng) {
  //     this.map.setView(layer.getLatLng());
  //   } else {
  //     console.log('do not know how to show layer at point for:', layer);
  //   }
  //   layer.openPopup();
  // }
  //
  // let getLayerDataById = id => {
  //   let layer = this.drawObject.find(obj => obj._leaflet_id === id);
  //   return getTargetData(layer);
  // }
  //
  // let getTargetData = (layer) => {
  //   let {layerType} = layer;
  //   let target = {
  //     id: layer._leaflet_id,
  //     type: layerType
  //   };
  //   if (layerType === 'marker' || layerType === 'circlemarker') {
  //     target.latlngs = [layer.getLatLng()];
  //   } else if (layerType === 'polyline') {
  //     target.latlngs = layer.editing.latlngs[0];
  //   } else if (layerType === 'polygon') {
  //     target.latlngs = layer.editing.latlngs[0][0];
  //   } else if (layerType === 'rectangle') {
  //     target.latlngs = [layer.getBounds().getSouthWest(), layer.getBounds().getNorthEast()];
  //   } else if (layerType === 'circle') {
  //     target.latlngs = [layer.getLatLng()];
  //     target.radiusInMeters = layer.getRadius();
  //     target.radiusInNM = meters2nm(target.radiusInMeters);
  //   }
  //   return target;
  // }

// 新建绘制控件时调用
  drawLayerCreated (evt) {
    let {layerType, layer} = evt;
    // console.log(layerType, layer);
    layer.layerType = layerType;
    this.drawObject.push(layer);
    if (this._layerChangeCallback) {
      let target = getTargetData(layer);
      // console.log('drawLayerCreated::', layer, target);
      this._layerChangeCallback('create', [target], layer);
    }
  }

// 修改绘制控件时调用
  drawLayerUpdated (evt) {
    let layers = evt.layers;
    let targetAry = [];
    layers.eachLayer(layer => {
      let target = getTargetData(layer);
      targetAry.push(target);
    })
    this._layerChangeCallback('update', targetAry);
  }

  drawLayerDeleted (evt) {
    let layers = evt.layers;
    let targetAry = [];
    layers.eachLayer(layer => {
      let idx = this.drawObject.findIndex(obj => obj._leaflet_id === layer._leaflet_id);
      this.drawObject.splice(idx, 1);

      let target = getTargetData(layer);
      targetAry.push(target);
    })
    this._layerChangeCallback('delete', targetAry);
  }

  // 查询视野内的船舶位置
  startQueryShipInBound () {
    if (this.hideAisLayer) {
      return
    }
    // console.log(ShipLocationService)
    // console.log('query ship in bound:::::', this.map)
    this.queryShipTimer = setTimeout(this.startQueryShipInBound.bind(this), SHIP_QUERY_INTERVAL);
    // let tmStr = null;
    // if (!this.lastAisTime) {
    //   // 地图位置发生变化时，只查询6小时内的数据，当前ais时间保存的是北京时间,有8小时差
    //   tmStr = moment().add(-6, 'h').utc().format();
    //   // console.log(moment().utc().format(), tmStr);
    // } else {
    //   tmStr = moment().add(-30, 's').utc().format();
    // }
    let fromTime = 0;
    if (this.lastAisTime) {
      this.lastAisTime = new Date().getTime();
      fromTime = this.lastAisTime - SHIP_QUERY_INTERVAL - SHIP_QUERY_INTERVAL;
    } else {
      // 默认只显示最后2小时内有过定位数据的船只
      fromTime = new Date().getTime() - (1000 * 3600 * 2)
    }

    this.lastAisTime = moment().utc().format();

    shipLocationService.getShipsInRect(this.map.getBounds().getSouthWest(), this.map.getBounds().getNorthEast(), fromTime).then(res => {
      // console.log('got locations:::::count::::', res.length, fromTime);
      this.drawShips(res, fromTime === 0)
    })
    // console.log('timer:', this.queryShipTimer);
    // ShipLocationService.queryShips(this.map.getBounds().getSouthWest(), this.map.getBounds().getNorthEast(), tmStr).then(res => {
    //   if (res && res.data) {
    //     drawShips(res.data);
    //   }
    // })
  }

  querySingleShipByMmsi (mmsi) {
    shipLocationService.getShipByMmsi(mmsi).then(res => {
      this.drawShips(res)
    })
  }

// 停止查询船舶位置
  stopQueryShipInBound () {
    clearTimeout(this.queryShipTimer)
  }

  resetShipLabels (zoomLevel) {
    if (this.prevZoomLevel > 13) {
      if (zoomLevel <= 13) {
        // 缩小地图，清除所有标签
        Object.values(this.shipLabels).forEach(lbl => {
          this.shipLayer.removeTrack(lbl)
        });
        // 取消选中船焦点
        if (this.focusShipMarker) {
          this.focusShipMarker.blur()
        }
      } else if (zoomLevel !== this.prevZoomLevel) {
        // 放大地图，重新调整所有标签位置
        Object.values(this.shipSet).forEach(ship => {
          let latLng = this.getLabelLatLng(ship.latLng)
          this.shipLabels[ship.terminalCode].setLatLng(latLng)
        })
      }
    } else {
      if (zoomLevel > 13) {
        // 放大地图，添加全部标签
        Object.values(this.shipSet).forEach(ship => {
          // console.log('ship:', ship);
          let latLng = this.getLabelLatLng(ship.latLng)
          this.shipLabels[ship.terminalCode].setLatLng(latLng)
          this.shipLayer.addTrack(this.shipLabels[ship.terminalCode])
        });
      }
    }
  }

  hideShips (hideAll = false) {

    Object.keys(this.shipMarkers).forEach(mmsi => {
      if (hideAll || !this.shipMarkers[mmsi].remainOnMap) {
        // this.shipMarkers[mmsi].remove();
        this.shipLayer.removeTrack(this.shipMarkers[mmsi])
        // delete this.shipMarkers[mmsi];
      }
    });
  }

  // hideAllShips () {
  //   this.hideShips(true)
  // }

  on (eventName, callback) {
    if (eventName === 'shipOnClick') {
      this._shipOnClickCallback = callback;
    }
  }

  // 绘制全部船舶
  drawShips (shipArray, forceAdd) {

    shipArray.forEach(ship => {
      let oldShip = this.shipSet[ship.terminalCode]
      if (!!oldShip) {
        // if (oldShip.latLng.lat !== ship.latitude || oldShip.latLng.lng !== ship.longitude) {
        // 查询结果船舶经纬度发生变化，更新对应的数据
        oldShip.latLng = {lat: ship.latitude, lng: ship.longitude}
        oldShip.aisTime = ship.aisTime
        oldShip.course = ship.course
        oldShip.heading = ship.trueHeading
        ship.flag = 'update'
        // }
      } else {
        ship.color = this.getShipColor(ship.shipType)
        this.shipSet[ship.terminalCode] = {
          color: ship.color,
          shipName: ship.shipName,
          shipType: ship.shipType,
          shipSize: ship.shipSize,
          terminalCode: ship.terminalCode,
          latLng: {lat: ship.latitude, lng: ship.longitude},
          aisTime: ship.aisTime,
          course: ship.course,
          heading: ship.trueHeading,
          speed: ship.speed
        }
        ship.flag = 'add'
      }
    })
    // console.log('ship set::::::', this.shipSet)

    shipArray.forEach(ship => {
      // console.log('sssss', ship);
      if (ship.flag === 'add') {
        let marker = this.drawOneShip(ship);
        if (marker) {
          this.shipMarkers[ship.terminalCode] = marker;
          this.shipLayer.addTrack(marker);
        }
      } else if (ship.flag === 'update') {
        let marker = this.shipMarkers[ship.terminalCode];
        if (marker) {
          marker.setData(ship);
          if (ship.remainOnMap || forceAdd) {
            this.shipLayer.addTrack(marker);
          }
          let latLng = this.getLabelLatLng({lat: ship.latitude, lng: ship.longitude});
          this.shipLabels[ship.terminalCode].setLatLng(latLng);

          if (marker.getTrackId() === this.focusTrackId && this.focusMarker) {
            // console.log(marker.get)
            this.focusMarker.setLatLng(marker.getLatLng())
          }
        }
      }
    })
  }

  /**
   * 绘制船只
   * @param ship 位置数据
   * @param remain 海图11级以下时是否隐藏
   * @returns {*}
   */
  drawOneShip (ship) {
    // ship.shipInfo = ship.shipInfo || dataGenerator.getShipInfo(ship.terminalCode);
    // if (ship.shipInfo.color === config.SHIP_COLOR_DEFAULT) {
    //   return null;
    // }

    let myIcon = L.divIcon({
      className: '',
      html: '<div class="ship-label"><span>' + (ship.shipName || ship.terminalCode) + '</span></div>'
    });
    let latLng = L.latLng([ship.latitude, ship.longitude])
    let lblMarker = L.marker(latLng, {icon: myIcon})
    this.shipLabels[ship.terminalCode] = lblMarker

    // console.log('new add ship::::', ship.terminalCode);
    let marker = L.trackSymbol({lat: ship.latitude, lng: ship.longitude}, {
      trackId: ship.terminalCode,
      fill: true,
      fillColor: ship.color,
      fillOpacity: 1.0,
      stroke: true,
      color: '#000',
      opacity: 1.0,
      weight: 1.0,
      speed: ship.speed,
      course: ship.course,
      heading: ship.trueHeading,
      minSilouetteZoom: 11
    }).bindTooltip(this.makeShipTooltip.bind(this))
    marker.on({
      'mouseover': e => {
        // console.log(e.target);
        marker.openTooltip()
      },
      'mouseout': e => {
        marker.closeTooltip()
      },
      'click': e => {
        this.selectMarker(marker, ship, true)
      }
    })
    if (this.selectMmsi === ship.terminalCode) {
      this.selectMarker(marker, ship, false)
      this.selectMmsi = null
    }
    if (ship.remainOnMap) {
      marker.remainOnMap = true
    }
    return marker
  }
  locateShip (mmsi, showDetail = false) {
    this.selectMmsi = mmsi
    let ship = this.shipSet[mmsi]
    let marker = this.shipMarkers[mmsi]
    if (!ship || !marker) {
      return this.querySingleShipByMmsi(mmsi)
    }
    this.selectMarker(marker, ship)
  }
  selectMarker (marker, ship, showDetail = false) {
    if (this.focusShipMarker) {
      this.focusShipMarker.blur()
    }
    marker.focus()
    this.focusTrackId = marker.getTrackId()
    if (!this.focusMarker) {
      this.focusMarker = L.focusMarker({lat: ship.latitude, lng: ship.longitude}, {
        trackId: 'focusMarkerId',
        fill: false,
        stroke: true,
        color: '#ef262e',
        opacity: 1.0,
        weight: 3.0
      })
      this.shipLayer.addTrack(this.focusMarker)
    } else {
      this.focusMarker.setLatLng(marker.getLatLng())
    }
    if (this.focusShipMarker) {
      this.focusShipMarker.closeTooltip()
    }
    this.focusShipMarker = marker
    setTimeout(() => {
      marker.openTooltip()
    }, 500)

    if (showDetail) {
      this.map.setView(marker.getLatLng())
      if (this._shipOnClickCallback) {
        this._shipOnClickCallback(ship)
      }
    }
  }
  // 船名标注位置
  getLabelLatLng (latlng) {
    // console.log(gps);
    let latLng = L.latLng([latlng.lat, latlng.lng]);
    let pt = this.map.latLngToContainerPoint(latLng);
    let newPt = L.point([pt.x - 20, pt.y - 15]);
    latLng = this.map.containerPointToLatLng(newPt);
    return [latLng.lat, latLng.lng];
  }

  getShipColor (shipType) {
    if (!shipType) {
      return config.SHIP_COLOR_DEFAULT
    }
    let c = config.SHIP_COLOR_ARRAY.find(s => shipType.startsWith(s.code))
    if (c) {
      return c.color
    }
    return config.SHIP_COLOR_DEFAULT
  }

  makeShipTooltip (marker) {
// console.log(marker.getTrackId(), this.shipSet)
//     console.log('ship set:::::::::', marker.getTrackId(), this.shipSet)
    let ship = this.shipSet[marker.getTrackId()];
    let tm = moment(ship.aisTime).format('YYYY-MM-DD HH:mm:ss');
    // ship.shipInfo = ship.shipInfo || dataGenerator.getShipInfo(ship.terminalCode);
    // console.log(`course=${ship.course}, heading=${ship.heading}`, marker.getCourse(), marker.getHeading());
    return `<div class="ship-tt-container">${ship.shipName || ship.terminalCode}<hr/><div>标识代码：${ship.terminalCode}</div><div>船舶速度：${ship.speed}节</div><div>最后时间：${tm}</div></div>`
  }
}

export default DrawShip.getInstance()
